<!--
  BaseInputText.vue - 基础文本输入框组件
  
  这是一个可复用的基础输入框组件，支持v-model双向数据绑定
  设计目标：
  1. 封装原生input元素，提供统一的样式和行为
  2. 支持v-model语法糖
  3. 透传所有事件监听器
  4. 可在整个项目中复用
-->

<template>
    <!-- 
      渲染一个文本输入框
      :value="value" - 绑定输入框的值到props.value
      v-on="listeners" - 使用计算属性透传所有事件监听器
      class="input" - 应用自定义样式类
    -->
    <input 
        type="text" 
        class="input" 
        :value="value" 
        v-on="listeners" 
    />
</template>

<script>
/**
 * BaseInputText组件脚本部分
 * 
 * 实现了一个支持v-model的输入框组件
 * v-model的工作原理：
 * 1. 父组件传入value prop
 * 2. 子组件在输入时触发input事件
 * 3. 父组件监听input事件并更新绑定的数据
 */

export default {
    // 组件名称，用于调试和Vue DevTools
    name: 'BaseInputText',
    
    // 组件接收的属性
    props: {
        // value属性 - 输入框的值
        value: {
            type: String, // 数据类型为字符串
            default: "", // 默认值为空字符串
        },
    },
    
    // 计算属性
    computed: {
        /**
         * listeners计算属性
         * 
         * 用于处理事件监听器的透传和v-model支持
         * 这是Vue 2.x中实现自定义组件v-model的标准模式
         */
        listeners() {
            return {
                // 使用扩展运算符透传父组件传入的所有事件监听器
                // 这样父组件可以监听input元素的所有原生事件
                ...this.$listeners,
                
                // 重写input事件监听器以支持v-model
                // 当用户输入时，触发input事件并传递新的值
                // 这是v-model工作的关键：子组件通过$emit('input', newValue)通知父组件
                input: (event) => this.$emit("input", event.target.value),
            };
        },
    },
};
</script>

<style lang="scss" scoped>
/**
 * 组件样式 - 使用scoped确保样式只作用于当前组件
 * 
 * scoped的作用：
 * 1. 防止样式污染其他组件
 * 2. Vue会为每个scoped样式添加唯一的属性选择器
 * 3. 确保组件样式的封装性
 */

// 导入全局变量，可以使用$vue-blue等变量
@import "../variables.scss";

// 输入框样式
.input {
    // 宽度占满父容器
    width: 100%;
    
    // 内边距，提供舒适的输入体验
    // 上下8px，左右10px
    padding: 8px 10px;
    
    // 边框样式，使用Vue主题色
    // 1px实线边框，颜色为$vue-blue变量定义的深蓝色
    border: 1px solid $vue-blue;
    
    // 可以添加更多样式：
    // border-radius: 4px; // 圆角
    // font-size: 14px; // 字体大小
    // outline: none; // 移除默认焦点轮廓
    // transition: border-color 0.3s; // 边框颜色过渡动画
    
    // &:focus {
    //     border-color: $vue-green; // 焦点时的边框颜色
    // }
}
</style>
